(function($) {
	var REGEX_EMAIL = '([a-z0-9!#$%&\'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&\'*+/=?^_`{|}~-]+)*@' + '(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)';
	var $inputTemplate = '<div class="noime jma_div_txt" id="" style="cursor: text;">' + '<div style="position: absolute; color: rgb(160, 160, 160); padding-top: 1px; display: none;">' + '</div>' + '<div style="float:left;border:none;overflow:hidden;width:13px;" class="jma_addr_text">' + '<input type="text" accesskey="t" ime-mode="disabled" style="border:none;outline:none;-webkit-appearance:none;width:100%;ime-mode:active" class="jma_js_input" tabindex="1" autocomplete="off">' + '</div>' + '<div style="border: medium none; margin: 0px; padding: 0px; clear: both;">' + '<input type="text" tabindex="-1" style="position:absolute;border:none;padding:0;width:10px;left:-9999px;top:-9999px;">' + '</div>' + '</div>';
	var $emailWithNickTemplate = '<div data-value="{0}" title="{1}" style="float:left;white-space:nowrap;" class="jma_addr_base jma_addr_normal ">' + '<b>{2}</b>' + '<span>' + '&lt;{3}&gt;' + '</span>' + '<span class="jma_semicolon">;</span>' + '</div>';
	var $emailNoneNickTemplate = '<div data-value="{0}" title="{1}" style="float:left;white-space:nowrap;" class="jma_addr_base jma_addr_normal ">' + '<b>{2}</b>' + '<span class="jma_semicolon">;</span>' + '</div>';
	var $emailErrorTemplate = '<div data-value="{0}" title="该地址格式有错误 ，请双击修改" style="float:left;white-space:nowrap;" class="jma_addr_base jma_addr_error ">' + '<b>{1}</b>' + '<span class="jma_semicolon">;</span>' + '</div>';
	$.fn.jMailAddr = function(options, params) {
		if (typeof options == 'string') {
			var method = $.fn.jMailAddr.methods[options];
			if (method) {
				return method(this, params);
			}
		}
		$Div = this.attr("id") + 'AreaCtrl';
		$.fn.jMailAddr.defaults = {
			width : '100%'
		};
		opts = $.extend({}, $.fn.jMailAddr.defaults, options);
		ini(this, opts);
	};

	function ini(target, opts) {
		$(target).hide();
		$(target).after($inputTemplate);
		$(target).next().attr("id", $Div);
		var $areaCtrl = $('#' + $Div);
		var js_input = $areaCtrl.find('[class=jma_js_input]');
		js_input.val("");
		if (typeof opts.width == "string") {
			$areaCtrl.css("width", opts.width);
		} else {
			$areaCtrl.css("width", opts.width + "px");
		}
		$areaCtrl.bind('click', function() {
			js_input.focus();
		});
		$areaCtrl.children().last().bind('keyup', function(e) {
			if (e.keyCode == 8) {
				js_input.parent().prev().remove();
				js_input.focus();
				resetValue($areaCtrl);
			} else if (e.keyCode == 37) {
				if ($areaCtrl.children().hasClass("jma_addr_select")) {
					js_input.parent().after($areaCtrl.children('.jma_addr_select'));
					$areaCtrl.children().removeClass("jma_addr_select").removeClass("jma_fn_list");
					js_input.focus();
				}
			} else if (e.keyCode == 39) {
				if ($areaCtrl.children().hasClass("jma_addr_select")) {
					js_input.parent().before($areaCtrl.children('.jma_addr_select'));
					$areaCtrl.children().removeClass("jma_addr_select").removeClass("jma_fn_list");
					js_input.focus();
				}
			} else if (e.keyCode == 46) {
				js_input.parent().next().remove();
				js_input.focus();
				resetValue($areaCtrl);
			}

		});
		js_input.focusin(function() {
			$areaCtrl.children().removeClass("jma_addr_select").removeClass("jma_fn_list");
		});
		js_input.blur(function() {
			append($areaCtrl, js_input);
		});
		js_input.bind('keyup', function(e) {
			if (((e.keyCode == 13 || e.keyCode == 186) && js_input.focus()) || e.keyCode == 59) {
				if (e.keyCode == 59) {
					js_input.val(js_input.val().substring(0, js_input.val().length - 1));
				}
				append($areaCtrl, js_input);
				return;
			} else if (e.keyCode == 8) {
				if ($.trim(js_input.val()) == "") {
					$areaCtrl.children().removeClass("jma_addr_select").removeClass("jma_fn_list");
					js_input.parent().prev().addClass("jma_addr_select").addClass("jma_fn_list");
					js_input.blur();
					$areaCtrl.children().last().find('input').focus();
				}
			} else if (e.keyCode == 37) {
				if (js_input.parent().prev().hasClass('jma_addr_base')) {
					js_input.parent().after(js_input.parent().prev());
				}
			} else if (e.keyCode == 39) {
				if (js_input.parent().next().hasClass('jma_addr_base')) {
					js_input.parent().before(js_input.parent().next());
				}
			} else if (e.keyCode == 46) {
				if ($.trim(js_input.val()) == "") {
					$areaCtrl.children().removeClass("jma_addr_select").removeClass("jma_fn_list");
					js_input.parent().next().addClass("jma_addr_select").addClass("jma_fn_list");
					js_input.blur();
					$areaCtrl.children().last().find('input').focus();
				}
			}
			$(this).parent().css("width", (js_input.val().length * 7) + 32 + "px");
			if (js_input.val().length == 0) {
				$(this).parent().css("width", "14px");
			}
		});
	}
	function append($areaCtrl, js_input) {
		var input = js_input.val();
		if ($.trim(input) == "") {
			return;
		}
		input = input.replace(';', '').replace('；', '');
		// input=input.replace('；', '');
		var isTrue = false;
		$areaCtrl.children('.jma_addr_base').each(function() {
			var value = $(this).attr("data-value");
			if (value == input) {
				isTrue = true;
				return false;
			}
		});
		if (isTrue) {
			js_input.val("");
			js_input.parent().css("width", "14px");
			return;
		}
		if ((new RegExp('^' + REGEX_EMAIL + '$', 'i')).test(input)) {
			doAppend($areaCtrl, js_input, {
				valid : true,
				email : input
			});
			return;
		}
		var match = input.match(new RegExp('^([^<]*)\<' + REGEX_EMAIL + '\>$', 'i'));
		if (match) {
			doAppend($areaCtrl, js_input, {
				valid : true,
				email : match[2],
				name : $.trim(match[1])
			});
			return;
		}
		doAppend($areaCtrl, js_input, {
			valid : false,
			email : input
		});
	}
	function doAppend($areaCtrl, js_input, params) {
		js_input.parent().before(appendDom(params));
		js_input.val("");
		js_input.parent().css("width", "14px");

		js_input.parent().prev().bind('mouseover', function() {
			$(this).addClass("jma_attbg");
		}).bind('mouseout', function() {
			$(this).removeClass("jma_attbg");
		}).bind('click', function() {
			$areaCtrl.unbind('click');
			$areaCtrl.children().removeClass("jma_addr_select").removeClass("jma_fn_list");
			$(this).addClass("jma_addr_select").addClass("jma_fn_list");
			js_input.parent().insertAfter($(this));
			js_input.parent().css("width", "2px");
			js_input.blur();
			$areaCtrl.children().last().find('input').focus();
			window.setTimeout(function() {
				$areaCtrl.bind('click', function() {
					js_input.focus();
				});
			}, 0);
		}).bind('dblclick', function() {
			var value = $(this).attr("data-value");
			js_input.val(value);
			js_input.parent().insertAfter($(this));
			js_input.parent().css("width", (value.length * 7) + 32 + "px");
			js_input.focus();
			$(this).remove();
		});
		resetValue($areaCtrl);
	}
	function resetValue($areaCtrl) {
		if ($areaCtrl.children('.jma_addr_normal').length > 0) {
			var s = "";
			$areaCtrl.children('.jma_addr_normal').each(function(key, value) {
				var _value = $(this).attr("data-value");
				if ((key + 1) == $areaCtrl.children('.jma_addr_normal').length) {
					s += _value;
				} else {
					s += (_value + ",");
				}
			});
			$areaCtrl.prev().val(s);
		} else {
			$areaCtrl.prev().val("");
		}
	}
	function appendDom(params) {
		if (params.valid) {
			if (params.name) {
				return format($emailWithNickTemplate, params.email, params.email, params.name, params.email);
			} else {
				return format($emailNoneNickTemplate, params.email, params.email, params.email);
			}
		} else {
			return format($emailErrorTemplate, params.email, params.email);
		}
	}
	function format(str) {
		for ( var i = 0; i < arguments.length - 1; i++) {
			str = str.replace("{" + i + "}", arguments[i + 1]);
		}
		return str;
	}

	function getValue(target) {
		return $(target).val();
	}

	function setValue(jq, value) {
		var $areaCtrl = $(jq).next();
		var js_input = $areaCtrl.find('[class=jma_js_input]');
		var email = value.email;
		if (email) {
			if ((new RegExp('^' + REGEX_EMAIL + '$', 'i')).test(email)) {
				value.valid = true;
			} else {
				alert("email is invalid");
				value.valid = false;
			}
			var isTrue = false;
			$areaCtrl.children('.jma_addr_base').each(function() {
				var _value = $(this).attr("data-value");
				if (_value == email) {
					isTrue = true;
					return false;
				}
			});
			if (isTrue) {
				js_input.val("");
				js_input.parent().css("width", "14px");
				return;
			}
			doAppend($areaCtrl, js_input, value);
		} else {
			alert("email is undefined");
		}
	}
	function validate(jq, value) {
		var $areaCtrl = $(jq).next();
		var count = $areaCtrl.children('.jma_addr_error').length;
		if (count > 0) {
			return false;
		}
		return true;
	}
	$.fn.jMailAddr.methods = {
		getValue : function(jq) {
			return getValue(jq);
		},
		setValue : function(jq, value) {
			var _value;
			if (typeof value == 'string') {
				_value = $.extend({}, {
					valid : true
				}, {
					email : value
				});
			} else {
				_value = $.extend({}, {
					valid : true
				}, value);
			}
			setValue(jq, _value);
		},
		validate : function(jq, value) {
			return validate(jq, value);
		}
	};
})(jQuery);